package org.microframework.base.core.log.service;

import java.lang.reflect.Method;
import java.util.Date;

import org.microframework.base.core.constant.SecurityConstants;
import org.microframework.base.core.log.domain.OperationLog;
import org.microframework.base.feign.logs.RemoteLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

/**
 * 异步调用日志服务
 */
@Slf4j
@Service
public class AsyncLogService
{
    @Autowired(required = false)
    private RemoteLogService remoteLogService;

    /**
     * 保存系统日志记录
     */
    @Async
    public void saveSysLog(OperationLog operLog)
    {
        try {
            if (remoteLogService != null) {
                // 转换为远程实体类
                org.microframework.base.model.logs.domain.OperationLog remoteLog = 
                    convertToRemoteLog(operLog);
                remoteLogService.saveLog(remoteLog, SecurityConstants.INNER);
            } else {
                log.warn("未注入RemoteLogService，无法保存日志");
            }
        } catch (Exception e) {
            log.error("异步保存日志失败：", e);
        }
    }
    
    /**
     * 转换为远程日志对象
     */
    private org.microframework.base.model.logs.domain.OperationLog convertToRemoteLog(OperationLog operLog) {
        org.microframework.base.model.logs.domain.OperationLog remoteLog = 
            new org.microframework.base.model.logs.domain.OperationLog();
        
        try {
            // 安全转换常见字段
            copyPropertyIfExists(operLog, remoteLog, "Title", String.class);
            copyPropertyIfExists(operLog, remoteLog, "BusinessType", Integer.class);
            copyPropertyIfExists(operLog, remoteLog, "Method", String.class);
            copyPropertyIfExists(operLog, remoteLog, "RequestMethod", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperatorType", Integer.class);
            copyPropertyIfExists(operLog, remoteLog, "OperName", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperUrl", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperIp", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperLocation", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperParam", String.class);
            copyPropertyIfExists(operLog, remoteLog, "JsonResult", String.class);
            copyPropertyIfExists(operLog, remoteLog, "Status", Integer.class);
            copyPropertyIfExists(operLog, remoteLog, "ErrorMsg", String.class);
            copyPropertyIfExists(operLog, remoteLog, "OperTime", Date.class);
            copyPropertyIfExists(operLog, remoteLog, "CostTime", Long.class);
            copyPropertyIfExists(operLog, remoteLog, "Browser", String.class);
            copyPropertyIfExists(operLog, remoteLog, "Os", String.class);
        } catch (Exception e) {
            log.error("日志字段映射异常: {}", e.getMessage());
        }
        
        return remoteLog;
    }
    
    /**
     * 安全地复制属性（如果目标对象存在相应setter方法）
     */
    private <T> void copyPropertyIfExists(Object source, Object target, String propertyName, Class<T> propertyType) {
        try {
            // 获取源对象getter方法
            Method getter = source.getClass().getMethod("get" + propertyName);
            if (getter != null) {
                // 尝试获取目标对象setter方法
                try {
                    Method setter = target.getClass().getMethod("set" + propertyName, propertyType);
                    if (setter != null) {
                        // 调用getter获取值，然后用setter设置值
                        Object value = getter.invoke(source);
                        if (value != null) {
                            setter.invoke(target, value);
                        }
                    }
                } catch (NoSuchMethodException e) {
                    // 目标对象没有对应的setter方法，忽略此属性
                    log.debug("目标对象不存在方法: set{}", propertyName);
                }
            }
        } catch (Exception e) {
            // 忽略任何反射异常
            log.debug("属性复制异常: {}", e.getMessage());
        }
    }
}
